home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / imap / ANSI / c-client / dummynt.c < prev    next >
C/C++ Source or Header  |  1996-03-15  |  15KB  |  600 lines

  1. /*
  2.  * Program:    Dummy routines for NT
  3.  *
  4.  * Author:    Mark Crispin
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date:    24 May 1993
  13.  * Last Edited:    14 March 1996
  14.  *
  15.  * Copyright 1996 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35.  
  36.  
  37. #include <ctype.h>
  38. #include <stdio.h>
  39. #include <errno.h>
  40. #include <fcntl.h>
  41. #include "mail.h"
  42. #include "osdep.h"
  43. #include <sys\stat.h>
  44. #include <dos.h>
  45. #include <io.h>
  46. #include "dummy.h"
  47. #include "misc.h"
  48.  
  49. long dummy_badname (char *tmp,char *s);
  50.  
  51. /* Dummy routines */
  52.  
  53.  
  54. /* Driver dispatch used by MAIL */
  55.  
  56. DRIVER dummydriver = {
  57.   "dummy",            /* driver name */
  58.   (DRIVER *) NIL,        /* next driver */
  59.   dummy_valid,            /* mailbox is valid for us */
  60.   dummy_parameters,        /* manipulate parameters */
  61.   dummy_find,            /* find mailboxes */
  62.   dummy_find_bboards,        /* find bboards */
  63.   dummy_find_all,        /* find all mailboxes */
  64.   dummy_find_all_bboards,    /* find all bboards */
  65.   dummy_subscribe,        /* subscribe to mailbox */
  66.   dummy_unsubscribe,        /* unsubscribe from mailbox */
  67.   dummy_subscribe_bboard,    /* subscribe to bboard */
  68.   dummy_unsubscribe_bboard,    /* unsubscribe from bboard */
  69.   dummy_create,            /* create mailbox */
  70.   dummy_delete,            /* delete mailbox */
  71.   dummy_rename,            /* rename mailbox */
  72.   dummy_open,            /* open mailbox */
  73.   dummy_close,            /* close mailbox */
  74.   dummy_fetchfast,        /* fetch message "fast" attributes */
  75.   dummy_fetchflags,        /* fetch message flags */
  76.   dummy_fetchstructure,        /* fetch message structure */
  77.   dummy_fetchheader,        /* fetch message header only */
  78.   dummy_fetchtext,        /* fetch message body only */
  79.   dummy_fetchbody,        /* fetch message body section */
  80.   dummy_setflag,        /* set message flag */
  81.   dummy_clearflag,        /* clear message flag */
  82.   dummy_search,            /* search for message based on criteria */
  83.   dummy_ping,            /* ping mailbox to see if still alive */
  84.   dummy_check,            /* check for new messages */
  85.   dummy_expunge,        /* expunge deleted messages */
  86.   dummy_copy,            /* copy messages to another mailbox */
  87.   dummy_move,            /* move messages to another mailbox */
  88.   dummy_append,            /* append string message to mailbox */
  89.   dummy_gc            /* garbage collect stream */
  90. };
  91.  
  92.  
  93.                 /* prototype stream */
  94. MAILSTREAM dummyproto = {&dummydriver};
  95.  
  96.                 /* driver parameters */
  97. static char *file_extension = NIL;
  98.  
  99. /* Dummy validate mailbox
  100.  * Accepts: mailbox name
  101.  * Returns: our driver if name is valid, NIL otherwise
  102.  */
  103.  
  104. DRIVER *dummy_valid (char *name)
  105. {
  106.   char tmp[MAILTMPLEN];
  107.   struct stat sbuf;
  108.                 /* must be valid local mailbox */
  109.   return (name && *name && (*name != '*') && (*name != '{') &&
  110.                 /* INBOX is always accepted */
  111.       ((!strcmp (ucase (strcpy (tmp,name)),"INBOX")) ||
  112.                 /* so is any valid file */
  113.        (mailboxfile (tmp,name) && !stat (tmp,&sbuf))))
  114.     ? &dummydriver : NIL;
  115. }
  116.  
  117.  
  118. /* Dummy manipulate driver parameters
  119.  * Accepts: function code
  120.  *        function-dependent value
  121.  * Returns: function-dependent return value
  122.  */
  123.  
  124. void *dummy_parameters (long function,void *value)
  125. {
  126.   switch ((int) function) {
  127.   case SET_EXTENSION:
  128.     if (file_extension) fs_give ((void **) &file_extension);
  129.     if (*(char *) value) file_extension = cpystr ((char *) value);
  130.     break;
  131.   case GET_EXTENSION:
  132.     value = (void *) file_extension;
  133.     break;
  134.   default:
  135.     value = NIL;        /* error case */
  136.     break;
  137.   }
  138.   return value;
  139. }
  140.  
  141. /* Dummy find list of subscribed mailboxes
  142.  * Accepts: mail stream
  143.  *        pattern to search
  144.  */
  145.  
  146. void dummy_find (MAILSTREAM *stream,char *pat)
  147. {
  148.   void *sdb = NIL;
  149.   char *t = sm_read (&sdb);
  150.   if (t) do if ((*t != '{') && strcmp (t,"INBOX") && pmatch (t,pat))
  151.     mm_mailbox (t);
  152.   while (t = sm_read (&sdb));    /* read subscription database */
  153. }
  154.  
  155.  
  156. /* Dummy find list of subscribed bboards
  157.  * Accepts: mail stream
  158.  *        pattern to search
  159.  */
  160.  
  161. void dummy_find_bboards (MAILSTREAM *stream,char *pat)
  162. {
  163.                 /* return silently */
  164. }
  165.  
  166. /* Dummy find list of all mailboxes
  167.  * Accepts: mail stream
  168.  *        pattern to search
  169.  */
  170.  
  171. void dummy_find_all (MAILSTREAM *stream,char *pat)
  172. {
  173.   struct _finddata_t f;
  174.   long   findrv;
  175.   char *s,tmp[MAILTMPLEN],file[MAILTMPLEN];
  176.   int i = 0;
  177.   int doinbox = T;
  178.                 /* directory specified in pattern? */
  179.   if ((s = strrchr (pat,'\\')) || (*(s = pat + 1) == ':')) {
  180.     strncpy (file,pat,i = (++s) - pat);
  181.     file[i] = '\0';        /* tie off prefix */
  182.   }
  183.                 /* make fully-qualified file name */
  184.   if (!mailboxfile (tmp,pat)) return;
  185.                 /* all files in directory */
  186.   strcpy ((s = strrchr (tmp,'\\')) ? s : tmp + 2,"\\*.");
  187.   strcat (s,file_extension ? file_extension : "*");
  188.                 /* loop through matching files */
  189.   if ((findrv = _findfirst (tmp,&f)) >= 0) do {
  190.                 /* suppress extension */
  191.     if (file_extension && (s = strchr (f.name,'.'))) *s = '\0';
  192.     strcpy (file + i,f.name);    /* build file name */
  193.     if (!strcmp (f.name,"INBOX")) doinbox = 0;
  194.     if (pmatch (file,pat)) mm_mailbox (file);
  195.   }
  196.   while (!_findnext (findrv,&f));
  197.   _findclose(findrv);
  198.                 /* always an INBOX */
  199.   if (doinbox && pmatch ("INBOX",pat)) mm_mailbox ("INBOX");
  200. }
  201.  
  202.  
  203. /* Dummy find list of all bboards
  204.  * Accepts: mail stream
  205.  *        pattern to search
  206.  */
  207.  
  208. void dummy_find_all_bboards (MAILSTREAM *stream,char *pat)
  209. {
  210.                 /* return silently */
  211. }
  212.  
  213. /* Dummy subscribe to mailbox
  214.  * Accepts: mail stream
  215.  *        mailbox to add to subscription list
  216.  * Returns: T on success, NIL on failure
  217.  */
  218.  
  219. long dummy_subscribe (MAILSTREAM *stream,char *mailbox)
  220. {
  221.   char tmp[MAILTMPLEN];
  222.   if (mailboxfile (tmp,mailbox)) return sm_subscribe (mailbox);
  223.   else return dummy_badname (tmp,mailbox);
  224. }
  225.  
  226.  
  227. /* Dummy unsubscribe to mailbox
  228.  * Accepts: mail stream
  229.  *        mailbox to delete from subscription list
  230.  * Returns: T on success, NIL on failure
  231.  */
  232.  
  233. long dummy_unsubscribe (MAILSTREAM *stream,char *mailbox)
  234. {
  235.   char tmp[MAILTMPLEN];
  236.   if (mailboxfile (tmp,mailbox)) return sm_unsubscribe (mailbox);
  237.   else return dummy_badname (tmp,mailbox);
  238. }
  239.  
  240.  
  241. /* Dummy subscribe to bboard
  242.  * Accepts: mail stream
  243.  *        bboard to add to subscription list
  244.  * Returns: T on success, NIL on failure
  245.  */
  246.  
  247. long dummy_subscribe_bboard (MAILSTREAM *stream,char *mailbox)
  248. {
  249.   return NIL;            /* always fails */
  250. }
  251.  
  252.  
  253. /* Dummy unsubscribe to bboard
  254.  * Accepts: mail stream
  255.  *        bboard to delete from subscription list
  256.  * Returns: T on success, NIL on failure
  257.  */
  258.  
  259. long dummy_unsubscribe_bboard (MAILSTREAM *stream,char *mailbox)
  260. {
  261.   return NIL;            /* always fails */
  262. }
  263.  
  264. /* Dummy create mailbox
  265.  * Accepts: mail stream
  266.  *        mailbox name to create
  267.  *        driver type to use
  268.  * Returns: T on success, NIL on failure
  269.  */
  270.  
  271. long dummy_create (MAILSTREAM *stream,char *mailbox)
  272. {
  273.   char tmp[MAILTMPLEN];
  274.   int fd;
  275.   if (!mailboxfile (tmp,mailbox)) return dummy_badname (tmp,mailbox);
  276.   if ((fd = open (tmp,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {
  277.                 /* failed */
  278.     sprintf (tmp,"Can't create mailbox %s: %s",mailbox,strerror (errno));
  279.     mm_log (tmp,ERROR);
  280.     return NIL;
  281.   }
  282.   close (fd);            /* close the file */
  283.   return LONGT;            /* return success */
  284. }
  285.  
  286.  
  287. /* Dummy delete mailbox
  288.  * Accepts: mail stream
  289.  *        mailbox name to delete
  290.  * Returns: T on success, NIL on failure
  291.  */
  292.  
  293. long dummy_delete (MAILSTREAM *stream,char *mailbox)
  294. {
  295.   return dummy_rename (stream,mailbox,NIL);
  296. }
  297.  
  298.  
  299. /* Mail rename mailbox
  300.  * Accepts: mail stream
  301.  *        old mailbox name
  302.  *        new mailbox name
  303.  * Returns: T on success, NIL on failure
  304.  */
  305.  
  306. long dummy_rename (MAILSTREAM *stream,char *old,char *new)
  307. {
  308.   char tmp[MAILTMPLEN],file[MAILTMPLEN],lock[MAILTMPLEN],lockx[MAILTMPLEN];
  309.                 /* make file name */
  310.   if (!mailboxfile (file,old)) return dummy_badname (tmp,old);
  311.   if (new && !mailboxfile (tmp,new)) return dummy_badname (tmp,new);
  312.                 /* do the rename or delete operation */
  313.   if (new ? rename (file,tmp) : unlink (file)) {
  314.     sprintf (tmp,"Can't %s mailbox %s: %s",new ? "rename" : "delete",old,
  315.          strerror (errno));
  316.     mm_log (tmp,ERROR);
  317.     return NIL;
  318.   }
  319.   return LONGT;            /* return success */
  320. }
  321.  
  322. /* Dummy open
  323.  * Accepts: stream to open
  324.  * Returns: stream on success, NIL on failure
  325.  */
  326.  
  327. MAILSTREAM *dummy_open (MAILSTREAM *stream)
  328. {
  329.   char tmp[MAILTMPLEN];
  330.   struct stat sbuf;
  331.   int fd = -1;
  332.                 /* OP_PROTOTYPE call or silence */
  333.   if (!stream || stream->silent) return NIL;
  334.   if (strcmp (ucase (strcpy (tmp,stream->mailbox)),"INBOX") &&
  335.       ((fd = open (mailboxfile (tmp,stream->mailbox),O_RDONLY,NIL)) < 0))
  336.     sprintf (tmp,"%s: %s",strerror (errno),stream->mailbox);
  337.   else {
  338.     if (fd >= 0) {        /* if got a file */
  339.       fstat (fd,&sbuf);        /* sniff at its size */
  340.       close (fd);
  341.       if (sbuf.st_size) sprintf (tmp,"Not a mailbox: %s",stream->mailbox);
  342.       else fd = -1;        /* a-OK */
  343.     }
  344.     if (fd < 0) {        /* no file, right? */
  345.       if (!stream->silent) {    /* only if silence not requested */
  346.                 /* say there are 0 messages */
  347.     mail_exists (stream,(long) 0);
  348.     mail_recent (stream,(long) 0);
  349.       }
  350.       return stream;        /* return success */
  351.     }
  352.   }
  353.   if (!stream->silent) mm_log (tmp,ERROR);
  354.   return NIL;            /* always fails */
  355. }
  356.  
  357.  
  358. /* Dummy close
  359.  * Accepts: MAIL stream
  360.  */
  361.  
  362. void dummy_close (MAILSTREAM *stream)
  363. {
  364.                 /* return silently */
  365. }
  366.  
  367. /* Dummy fetch fast information
  368.  * Accepts: MAIL stream
  369.  *        sequence
  370.  */
  371.  
  372. void dummy_fetchfast (MAILSTREAM *stream,char *sequence)
  373. {
  374.   fatal ("Impossible dummy_fetchfast");
  375. }
  376.  
  377.  
  378. /* Dummy fetch flags
  379.  * Accepts: MAIL stream
  380.  *        sequence
  381.  */
  382.  
  383. void dummy_fetchflags (MAILSTREAM *stream,char *sequence)
  384. {
  385.   fatal ("Impossible dummy_fetchflags");
  386. }
  387.  
  388.  
  389. /* Dummy fetch envelope
  390.  * Accepts: MAIL stream
  391.  *        message # to fetch
  392.  *        pointer to return body
  393.  * Returns: envelope of this message, body returned in body value
  394.  */
  395.  
  396. ENVELOPE *dummy_fetchstructure (MAILSTREAM *stream,long msgno,BODY **body)
  397. {
  398.   fatal ("Impossible dummy_fetchstructure");
  399.   return NIL;
  400. }
  401.  
  402.  
  403. /* Dummy fetch message header
  404.  * Accepts: MAIL stream
  405.  *        message # to fetch
  406.  * Returns: message header in RFC822 format
  407.  */
  408.  
  409. char *dummy_fetchheader (MAILSTREAM *stream,long msgno)
  410. {
  411.   fatal ("Impossible dummy_fetchheader");
  412.   return NIL;
  413. }
  414.  
  415. /* Dummy fetch message text (body only)
  416.  * Accepts: MAIL stream
  417.  *        message # to fetch
  418.  * Returns: message text in RFC822 format
  419.  */
  420.  
  421. char *dummy_fetchtext (MAILSTREAM *stream,long msgno)
  422. {
  423.   fatal ("Impossible dummy_fetchtext");
  424.   return NIL;
  425. }
  426.  
  427.  
  428. /* Berkeley fetch message body as a structure
  429.  * Accepts: Mail stream
  430.  *        message # to fetch
  431.  *        section specifier
  432.  * Returns: pointer to section of message body
  433.  */
  434.  
  435. char *dummy_fetchbody (MAILSTREAM *stream,long m,char *sec,unsigned long *len)
  436. {
  437.   fatal ("Impossible dummy_fetchbody");
  438.   return NIL;
  439. }
  440.  
  441.  
  442. /* Dummy set flag
  443.  * Accepts: MAIL stream
  444.  *        sequence
  445.  *        flag(s)
  446.  */
  447.  
  448. void dummy_setflag (MAILSTREAM *stream,char *sequence,char *flag)
  449. {
  450.   fatal ("Impossible dummy_setflag");
  451. }
  452.  
  453.  
  454. /* Dummy clear flag
  455.  * Accepts: MAIL stream
  456.  *        sequence
  457.  *        flag(s)
  458.  */
  459.  
  460. void dummy_clearflag (MAILSTREAM *stream,char *sequence,char *flag)
  461. {
  462.   fatal ("Impossible dummy_clearflag");
  463. }
  464.  
  465.  
  466. /* Dummy search for messages
  467.  * Accepts: MAIL stream
  468.  *        search criteria
  469.  */
  470.  
  471. void dummy_search (MAILSTREAM *stream,char *criteria)
  472. {
  473.                 /* return silently */
  474. }
  475.  
  476. /* Dummy ping mailbox
  477.  * Accepts: MAIL stream
  478.  * Returns: T if stream alive, else NIL
  479.  * No-op for readonly files, since read/writer can expunge it from under us!
  480.  */
  481.  
  482. long dummy_ping (MAILSTREAM *stream)
  483. {
  484.   char tmp[MAILTMPLEN];
  485.   MAILSTREAM *test = mail_open (NIL,stream->mailbox,OP_PROTOTYPE);
  486.                 /* swap streams if looks like a new driver */
  487.   if (test && (test->dtb != stream->dtb))
  488.     test = mail_open (stream,strcpy (tmp,stream->mailbox),NIL);
  489.   return test ? T : NIL;
  490. }
  491.  
  492.  
  493. /* Dummy check mailbox
  494.  * Accepts: MAIL stream
  495.  * No-op for readonly files, since read/writer can expunge it from under us!
  496.  */
  497.  
  498. void dummy_check (MAILSTREAM *stream)
  499. {
  500.   dummy_ping (stream);        /* invoke ping */
  501. }
  502.  
  503.  
  504. /* Dummy expunge mailbox
  505.  * Accepts: MAIL stream
  506.  */
  507.  
  508. void dummy_expunge (MAILSTREAM *stream)
  509. {
  510.                 /* return silently */
  511. }
  512.  
  513. /* Dummy copy message(s)
  514.  * Accepts: MAIL stream
  515.  *        sequence
  516.  *        destination mailbox
  517.  * Returns: T if copy successful, else NIL
  518.  */
  519.  
  520. long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox)
  521. {
  522.   fatal ("Impossible dummy_copy");
  523.   return NIL;
  524. }
  525.  
  526.  
  527. /* Dummy move message(s)
  528.  * Accepts: MAIL stream
  529.  *        sequence
  530.  *        destination mailbox
  531.  * Returns: T if move successful, else NIL
  532.  */
  533.  
  534. long dummy_move (MAILSTREAM *stream,char *sequence,char *mailbox)
  535. {
  536.   fatal ("Impossible dummy_move");
  537.   return NIL;
  538. }
  539.  
  540. /* Dummy append message string
  541.  * Accepts: mail stream
  542.  *        destination mailbox
  543.  *        stringstruct of message to append
  544.  * Returns: T on success, NIL on failure
  545.  */
  546.  
  547. long dummy_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date,
  548.            STRING *message)
  549. {
  550.   struct stat sbuf;
  551.   int fd = -1;
  552.   int e;
  553.   char tmp[MAILTMPLEN];
  554.   if ((strcmp (ucase (strcpy (tmp,mailbox)),"INBOX")) &&
  555.        ((fd = open (mailboxfile (tmp,mailbox),O_RDONLY,NIL)) < 0)) {
  556.     if ((e = errno) == ENOENT) {/* failed, was it no such file? */
  557.       mm_notify (stream,"[TRYCREATE] Must create mailbox before append",
  558.          (long) NIL);
  559.       return NIL;
  560.     }
  561.     sprintf (tmp,"%s: %s",strerror (e),mailbox);
  562.     mm_log (tmp,ERROR);        /* pass up error */
  563.     return NIL;            /* always fails */
  564.   }
  565.   else if (fd >= 0) {        /* found file? */
  566.     fstat (fd,&sbuf);        /* get its size */
  567.     close (fd);            /* toss out the fd */
  568.     if (sbuf.st_size) {        /* non-empty file? */
  569.       sprintf (tmp,"Indeterminate mailbox format: %s",mailbox);
  570.       mm_log (tmp,ERROR);
  571.       return NIL;
  572.     }
  573.   }
  574.   return (*default_proto ()->dtb->append) (stream,mailbox,flags,date,message);
  575. }
  576.  
  577.  
  578. /* Dummy garbage collect stream
  579.  * Accepts: mail stream
  580.  *        garbage collection flags
  581.  */
  582.  
  583. void dummy_gc (MAILSTREAM *stream,long gcflags)
  584. {
  585.                 /* return silently */
  586. }
  587.  
  588. /* Return bad file name error message
  589.  * Accepts: temporary buffer
  590.  *        file name
  591.  * Returns: long NIL always
  592.  */
  593.  
  594. long dummy_badname (char *tmp,char *s)
  595. {
  596.   sprintf (tmp,"Invalid mailbox name: %s",s);
  597.   mm_log (tmp,ERROR);
  598.   return (long) NIL;
  599. }
  600.